package emd24.telstudyresources;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Random;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
/**
 * This class represents the quiz that the user is taking. It contains a
 * list of Questions and keeps track of which question the user is on. 
 * 
 * <p>Bugs: NullPointerException occurs when trying to create Quiz from
 * Parcel. 
 * 
 * @author Evan Dyke
 *
 */
public class Quiz implements Parcelable{
	private ArrayList<Question> questions;
	private int currQuestionIndex;
	private String name;
	/**
	 * Creates an empty quiz.
	 * 
	 */
	public Quiz(){
		questions = new ArrayList<Question>();
	}
	/**
	 * Creates a quiz from a JSONObject. Throws a JSON Exception
	 *  if format is invalid.
	 * 
	 * @param js
	 * @throws JSONException
	 */
	public Quiz(JSONObject js, int numQuestions, boolean randomOrder) throws JSONException{
		
		int numberTotal = js.getInt("length");
		questions = new ArrayList<Question>();
		name = js.getString("name");
		JSONArray questions = js.getJSONArray("questions");
		Random rnd = new Random();
		int[] randArr = new int[numQuestions];

		if(randomOrder){
			// Randomly pick questions from JSON array 
			for(int i = 0; i < randArr.length; i++){
				boolean unique = false;			
				int val = -1;
				while(!unique){
					val = rnd.nextInt(numberTotal);
					unique = true;
					for(int j = 0; j < i; j++){
						if(val == randArr[j]){
							unique = false;
						}
					}
				}
				randArr[i] = val;
			}
		}

		Log.e("Values", Arrays.toString(randArr));
		rnd.nextInt(questions.length());
		for(int pos = 0; pos < randArr.length; pos++){
			if(randomOrder){
				this.questions.add(new Question(questions.getJSONObject(randArr[pos]), pos + 1));
			}else{
				this.questions.add(new Question(questions.getJSONObject(pos), pos + 1));
			}
		}
	}
	/**
	 * Creates a new Quiz from a Parcel.
	 * 
	 * @param in Parcel for quiz to be created from
	 */
	public Quiz(Parcel in) {
		this.questions = new ArrayList<Question>();
		in.readTypedList(this.questions, Question.CREATOR);
		this.currQuestionIndex = in.readInt();
		this.name = in.readString();
	}
	/**
	 * Adds a Question to the end of the quiz.
	 * 
	 * @param q Question to add to the quiz.
	 */
	public void addQuestion(Question q){
		questions.add(q);
	}

	/**
	 * Gets the question at a particular index.
	 * 
	 * @param index int of index to get question at (starting at 0).
	 * @return Question at index position
	 */
	public Question getQuestionAt(int index){
		return questions.get(index);
	}
	/**
	 * Gets the current question in the quiz.
	 * 
	 * @return the current question.
	 */
	public Question getCurrentQuestion(){
		return questions.get(this.getCurrQuestionIndex());
	}

	/**
	 * Gets the number of questions in the quiz.
	 * 
	 * @return number of questions in the quiz
	 */
	public int getNumQuestions(){
		return questions.size();
	}

	/**
	 * Gets the index of the current question.
	 * 
	 * @return the index of the current question
	 */
	public int getCurrQuestionIndex() {
		return currQuestionIndex;
	}

	/**
	 * Sets the index of the current question
	 * 
	 * @param currQuestionIndex the index of the current question to set
	 */
	public void setCurrQuestionIndex(int currQuestionIndex) {
		this.currQuestionIndex = currQuestionIndex;
	}
	public int getNumberCorrect(){
		int correct = 0;
		Iterator<Question> iter = this.questions.iterator();
		while(iter.hasNext()){
			if(iter.next().isCorrect()){
				correct++;
			}
		}
		return correct;
	}
	@Override
	public void writeToParcel(Parcel dest, int flags) {
		dest.writeTypedList(this.questions);
		dest.writeInt(this.currQuestionIndex);
		dest.writeString(this.name);
	}
	public static final Parcelable.Creator<Quiz> CREATOR
	= new Parcelable.Creator<Quiz>() {
		public Quiz createFromParcel(Parcel in) {
			return new Quiz(in);
		}

		@Override
		public Quiz[] newArray(int size) {
			return new Quiz[size];
		}

	};
	@Override
	public int describeContents() {
		return 0;
	}
	public Question[] toArray(){
		return this.questions.toArray(new Question[this.questions.size()]);
	}
	public Iterator<Question> iterator(){
		return this.questions.iterator();
	}
	
	/**
	 * Gets the index of the next question marked by the user in the
	 * quiz.
	 * 
	 * @param currIndex current position to look for next marked from 
	 * @return index of next marked question, -1 if does not exist
	 */
	public int getNextMarked(int currIndex){
		for (int q = currIndex + 1; q < this.questions.size(); q++){
			if(this.questions.get(q).isMarked()){
				return q;
			}
		}
		return -1;
	}
	/**
	 * Gets the index of the previous question marked by the user.
	 * 
	 * @param currIndex current position to look for next marked from
	 * @return index of previously marked question, -1 if doesn't exist
	 */
	public int getPrevMarked(int currIndex){
		for (int q = currIndex - 1; q >= 0; q--){
			if(this.questions.get(q).isMarked()){
				return q;
			}
		}
		return -1;
	}
	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}
	/**
	 * @param name the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}
}
